package cn.iocoder.yudao.module.worker.controller.app.trend;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent;
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl.UserIdempotentKeyResolver;
import cn.iocoder.yudao.framework.ip.core.utils.IPUtils;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.worker.dal.dataobject.clerk.ClerkDO;
import cn.iocoder.yudao.module.worker.dal.dataobject.clerkfans.ClerkFansDO;
import cn.iocoder.yudao.module.worker.dal.dataobject.trendlike.TrendLikeDO;
import cn.iocoder.yudao.module.worker.enums.trend.TrendTypeEnum;
import cn.iocoder.yudao.module.worker.service.clerk.ClerkService;
import cn.iocoder.yudao.module.worker.service.clerkfans.ClerkFansService;
import cn.iocoder.yudao.module.worker.service.trendlike.TrendLikeService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

import cn.iocoder.yudao.module.worker.controller.app.trend.vo.*;
import cn.iocoder.yudao.module.worker.dal.dataobject.trend.WorkerTrendDO;
import cn.iocoder.yudao.module.worker.service.trend.WorkerTrendService;

@Tag(name = "用户 APP - 店员动态")
@RestController
@RequestMapping("/worker/trend")
@Validated
public class AppWorkerTrendController {

    @Resource
    private WorkerTrendService trendService;

    @Resource
    private ClerkService clerkService;

    @Resource
    private TrendLikeService trendLikeService;

    @Resource
    private ClerkFansService clerkFansService;

    @Resource
    private MemberUserApi memberUserApi;

    @PostMapping("/create")
    @Operation(summary = "创建店员动态")
    @PreAuthenticated
    @Idempotent(timeout = 5, keyResolver = UserIdempotentKeyResolver.class, timeUnit = TimeUnit.MINUTES, message = "发帖过于频繁，请稍后再试")
    public CommonResult<Long> createTrend(@Valid @RequestBody AppWorkerTrendSaveReqVO createReqVO) {
        createReqVO.setUserId(getLoginUserId());
        createReqVO.setCity(IPUtils.getArea(getClientIP()).getName());
        return success(trendService.createTrend(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新店员动态")
    public CommonResult<Boolean> updateTrend(@Valid @RequestBody AppWorkerTrendSaveReqVO updateReqVO) {
        trendService.updateTrend(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除店员动态")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthenticated
    public CommonResult<Boolean> deleteTrend(@RequestParam("id") Long id) {
        trendService.deleteTrend(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得店员动态")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<AppWorkerTrendRespVO> getTrend(@RequestParam("id") Long id) {
        WorkerTrendDO trend = trendService.getTrend(id);
        return success(BeanUtils.toBean(trend, AppWorkerTrendRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得店员动态分页")
    public CommonResult<PageResult<AppWorkerTrendRespVO>> getTrendPage(@Valid AppWorkerTrendPageReqVO pageReqVO) {
        PageResult<WorkerTrendDO> pageResult = trendService.getTrendPage(pageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty());
        }
        List<ClerkDO> clerkList = clerkService.getClerkList(convertSet(pageResult.getList(), WorkerTrendDO::getWorkerClerkId));
        Map<Long, ClerkDO> mapClerk = convertMap(clerkList, ClerkDO::getId);

        List<MemberUserRespDTO> memberList = memberUserApi.getUserList(convertSet(pageResult.getList(), WorkerTrendDO::getUserId));
        Map<Long, MemberUserRespDTO> mapMember = convertMap(memberList, MemberUserRespDTO::getId);

        // 查询点赞列表
        List<TrendLikeDO> trendLikeList = trendLikeService.getTrendLikeList(pageReqVO.getUserId(), convertSet(pageResult.getList(), WorkerTrendDO::getId));
        Map<Long, TrendLikeDO> mapLike = convertMap(trendLikeList, TrendLikeDO::getTrendId);

        // 查询关注列表
        List<ClerkFansDO> clerkFansList = clerkFansService.getClerkFansList(pageReqVO.getUserId(), convertSet(pageResult.getList(), WorkerTrendDO::getWorkerClerkId));
        Map<Long, ClerkFansDO> mapFans = convertMap(clerkFansList, ClerkFansDO::getWorkerClerkId);

        PageResult<AppWorkerTrendRespVO> page = BeanUtils.toBean(pageResult, AppWorkerTrendRespVO.class);
        for(AppWorkerTrendRespVO trendRespVO : page.getList()){
            trendRespVO.setLike(ObjectUtil.isNotNull(mapLike.get(trendRespVO.getId())));
            trendRespVO.setFans(ObjectUtil.isNotNull(mapFans.get(trendRespVO.getWorkerClerkId())));
            if(TrendTypeEnum.isClerk(trendRespVO.getTrendType())){
                trendRespVO.setNickname(mapClerk.getOrDefault(trendRespVO.getWorkerClerkId(), new ClerkDO()).getNickname());
                trendRespVO.setAvatar(mapClerk.getOrDefault(trendRespVO.getWorkerClerkId(), new ClerkDO()).getAvatar());
                trendRespVO.setSex(mapClerk.getOrDefault(trendRespVO.getWorkerClerkId(), new ClerkDO()).getSex());
                trendRespVO.setAge(mapClerk.getOrDefault(trendRespVO.getWorkerClerkId(), new ClerkDO()).getAge());
            }else{
                trendRespVO.setNickname(mapMember.getOrDefault(trendRespVO.getUserId(), new MemberUserRespDTO()).getNickname());
                trendRespVO.setAvatar(mapMember.getOrDefault(trendRespVO.getUserId(), new MemberUserRespDTO()).getAvatar());
                String sex = String.valueOf(mapMember.getOrDefault(trendRespVO.getUserId(), new MemberUserRespDTO()).getSex());
                // 转换性别
                if("1".equals(sex)){
                    // 男
                    sex = "0";
                }else if("2".equals(sex)){
                    // 女
                    sex = "1";
                }
                trendRespVO.setSex(sex);
                trendRespVO.setAge(mapMember.getOrDefault(trendRespVO.getUserId(), new MemberUserRespDTO()).getAge());
            }
        }

        return success(page);
    }

    @GetMapping("/myPage")
    @Operation(summary = "获得店员动态分页")
    @PreAuthenticated
    public CommonResult<PageResult<AppWorkerTrendRespVO>> getMyTrendPage(@Valid AppWorkerTrendPageReqVO pageReqVO) {
        pageReqVO.setUserId(getLoginUserId());
        PageResult<WorkerTrendDO> pageResult = trendService.getMyTrendPage(pageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty());
        }
        List<ClerkDO> clerkList = clerkService.getClerkList(convertSet(pageResult.getList(), WorkerTrendDO::getWorkerClerkId));
        Map<Long, ClerkDO> mapClerk = convertMap(clerkList, ClerkDO::getId);

        List<MemberUserRespDTO> memberList = memberUserApi.getUserList(convertSet(pageResult.getList(), WorkerTrendDO::getUserId));
        Map<Long, MemberUserRespDTO> mapMember = convertMap(memberList, MemberUserRespDTO::getId);

        // 查询点赞列表
        List<TrendLikeDO> trendLikeList = trendLikeService.getTrendLikeList(pageReqVO.getUserId(), convertSet(pageResult.getList(), WorkerTrendDO::getId));
        Map<Long, TrendLikeDO> mapLike = convertMap(trendLikeList, TrendLikeDO::getTrendId);

        // 查询关注列表
        List<ClerkFansDO> clerkFansList = clerkFansService.getClerkFansList(pageReqVO.getUserId(), convertSet(pageResult.getList(), WorkerTrendDO::getWorkerClerkId));
        Map<Long, ClerkFansDO> mapFans = convertMap(clerkFansList, ClerkFansDO::getWorkerClerkId);

        PageResult<AppWorkerTrendRespVO> page = BeanUtils.toBean(pageResult, AppWorkerTrendRespVO.class);
        for(AppWorkerTrendRespVO trendRespVO : page.getList()){
            trendRespVO.setLike(ObjectUtil.isNotNull(mapLike.get(trendRespVO.getId())));
            trendRespVO.setFans(ObjectUtil.isNotNull(mapFans.get(trendRespVO.getWorkerClerkId())));
            if(TrendTypeEnum.isClerk(trendRespVO.getTrendType())){
                trendRespVO.setNickname(mapClerk.getOrDefault(trendRespVO.getWorkerClerkId(), new ClerkDO()).getNickname());
                trendRespVO.setAvatar(mapClerk.getOrDefault(trendRespVO.getWorkerClerkId(), new ClerkDO()).getAvatar());
                trendRespVO.setSex(mapClerk.getOrDefault(trendRespVO.getWorkerClerkId(), new ClerkDO()).getSex());
                trendRespVO.setAge(mapClerk.getOrDefault(trendRespVO.getWorkerClerkId(), new ClerkDO()).getAge());
            }else{
                trendRespVO.setNickname(mapMember.getOrDefault(trendRespVO.getUserId(), new MemberUserRespDTO()).getNickname());
                trendRespVO.setAvatar(mapMember.getOrDefault(trendRespVO.getUserId(), new MemberUserRespDTO()).getAvatar());
                String sex = String.valueOf(mapMember.getOrDefault(trendRespVO.getUserId(), new MemberUserRespDTO()).getSex());
                // 转换性别
                if("1".equals(sex)){
                    // 男
                    sex = "0";
                }else if("2".equals(sex)){
                    // 女
                    sex = "1";
                }
                trendRespVO.setSex(sex);
                trendRespVO.setAge(mapMember.getOrDefault(trendRespVO.getUserId(), new MemberUserRespDTO()).getAge());
            }
        }

        return success(page);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出店员动态 Excel")
    @ApiAccessLog(operateType = EXPORT)
    public void exportTrendExcel(@Valid AppWorkerTrendPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<WorkerTrendDO> list = trendService.getTrendPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "店员动态.xls", "数据", AppWorkerTrendRespVO.class,
                        BeanUtils.toBean(list, AppWorkerTrendRespVO.class));
    }

}